home *** CD-ROM | disk | FTP | other *** search
/ SGI Freeware 1999 August / SGI Freeware 1999 August.iso / dist / samba.idb / usr / samba / src / source / nmbd.c.z / nmbd.c
Encoding:
C/C++ Source or Header  |  1998-10-28  |  20.3 KB  |  804 lines

  1. /*
  2.    Unix SMB/Netbios implementation.
  3.    Version 1.9.
  4.    NBT netbios routines and daemon - version 2
  5.    Copyright (C) Andrew Tridgell 1994-1998
  6.    
  7.    This program is free software; you can redistribute it and/or modify
  8.    it under the terms of the GNU General Public License as published by
  9.    the Free Software Foundation; either version 2 of the License, or
  10.    (at your option) any later version.
  11.    
  12.    This program is distributed in the hope that it will be useful,
  13.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  14.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15.    GNU General Public License for more details.
  16.    
  17.    You should have received a copy of the GNU General Public License
  18.    along with this program; if not, write to the Free Software
  19.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20.    
  21.    Revision History:
  22.  
  23.    14 jan 96: lkcl@pires.co.uk
  24.    added multiple workgroup domain master support
  25.  
  26. */
  27.  
  28. #include "includes.h"
  29.  
  30. extern int DEBUGLEVEL;
  31.  
  32. extern pstring debugf;
  33. pstring servicesf = CONFIGFILE;
  34.  
  35. extern pstring scope;
  36.  
  37. int ClientNMB       = -1;
  38. int ClientDGRAM     = -1;
  39. int global_nmb_port = -1;
  40.  
  41. extern pstring myhostname;
  42. static pstring host_file;
  43. extern pstring myname;
  44. extern fstring myworkgroup;
  45. extern char **my_netbios_names;
  46.  
  47. extern BOOL global_in_nmbd;
  48.  
  49. /* are we running as a daemon ? */
  50. static BOOL is_daemon = False;
  51.  
  52. /* have we found LanMan clients yet? */
  53. BOOL found_lm_clients = False;
  54.  
  55. /* what server type are we currently */
  56.  
  57. time_t StartupTime = 0;
  58.  
  59. extern struct in_addr ipzero;
  60.  
  61. /**************************************************************************** **
  62.   catch a sigterm
  63.  **************************************************************************** */
  64. static int sig_term(void)
  65. {
  66.   BlockSignals(True,SIGTERM);
  67.   
  68.   DEBUG(0,("Got SIGTERM: going down...\n"));
  69.   
  70.   /* Write out wins.dat file if samba is a WINS server */
  71.   wins_write_database();
  72.   
  73.   /* Remove all SELF registered names. */
  74.   release_my_names();
  75.   
  76.   /* Announce all server entries as 0 time-to-live, 0 type. */
  77.   announce_my_servers_removed();
  78.  
  79.   /* If there was an async dns child - kill it. */
  80.   kill_async_dns_child();
  81.  
  82.   exit(0);
  83.  
  84.   /* Keep compiler happy.. */
  85.   return 0;
  86. } /* sig_term */
  87.  
  88. /**************************************************************************** **
  89.  catch a sighup
  90.  **************************************************************************** */
  91. static int sig_hup(void)
  92. {
  93.   BlockSignals( True, SIGHUP );
  94.  
  95.   DEBUG( 0, ( "Got SIGHUP dumping debug info.\n" ) );
  96.  
  97.   write_browse_list( 0, True );
  98.  
  99.   dump_all_namelists();
  100.   reload_services( True );
  101.  
  102.   set_samba_nb_type();
  103.  
  104.   BlockSignals(False,SIGHUP);
  105. #ifndef DONT_REINSTALL_SIG
  106.   signal(SIGHUP,SIGNAL_CAST sig_hup);
  107. #endif
  108.   return(0);
  109. } /* sig_hup */
  110.  
  111. /**************************************************************************** **
  112.  catch a sigpipe
  113.  **************************************************************************** */
  114. static int sig_pipe(void)
  115. {
  116.   BlockSignals( True, SIGPIPE );
  117.  
  118.   DEBUG( 0, ("Got SIGPIPE\n") );
  119.   if ( !is_daemon )
  120.     exit(1);
  121.   BlockSignals( False, SIGPIPE );
  122. #ifndef DONT_REINSTALL_SIG
  123.   signal(SIGHUP,SIGNAL_CAST sig_pipe);
  124. #endif
  125.   return(0);
  126. } /* sig_pipe */
  127.  
  128. #if DUMP_CORE
  129. /**************************************************************************** **
  130.  prepare to dump a core file - carefully!
  131.  **************************************************************************** */
  132. static BOOL dump_core(void)
  133. {
  134.   char *p;
  135.   pstring dname;
  136.   pstrcpy( dname, debugf );
  137.   if ((p=strrchr(dname,'/')))
  138.     *p=0;
  139.   pstrcat( dname, "/corefiles" );
  140.   mkdir( dname, 0700 );
  141.   sys_chown( dname, getuid(), getgid() );
  142.   chmod( dname, 0700 );
  143.   if ( chdir(dname) )
  144.     return( False );
  145.   umask( ~(0700) );
  146.  
  147. #ifndef NO_GETRLIMIT
  148. #ifdef RLIMIT_CORE
  149.   {
  150.     struct rlimit rlp;
  151.     getrlimit( RLIMIT_CORE, &rlp );
  152.     rlp.rlim_cur = MAX( 4*1024*1024, rlp.rlim_cur );
  153.     setrlimit( RLIMIT_CORE, &rlp );
  154.     getrlimit( RLIMIT_CORE, &rlp );
  155.     DEBUG( 3, ( "Core limits now %d %d\n", rlp.rlim_cur, rlp.rlim_max ) );
  156.   }
  157. #endif
  158. #endif
  159.  
  160.  
  161.   DEBUG( 0, ( "Dumping core in %s\n",dname ) );
  162.   return( True );
  163. } /* dump_core */
  164. #endif
  165.  
  166.  
  167. /**************************************************************************** **
  168.  possibly continue after a fault
  169.  **************************************************************************** */
  170. static void fault_continue(void)
  171. {
  172. #if DUMP_CORE
  173.   dump_core();
  174. #endif
  175. } /* fault_continue */
  176.  
  177. /**************************************************************************** **
  178.  expire old names from the namelist and server list
  179.  **************************************************************************** */
  180. static void expire_names_and_servers(time_t t)
  181. {
  182.   static time_t lastrun = 0;
  183.   
  184.   if ( !lastrun )
  185.     lastrun = t;
  186.   if ( t < (lastrun + 5) )
  187.     return;
  188.   lastrun = t;
  189.  
  190.   /*
  191.    * Expire any timed out names on all the broadcast
  192.    * subnets and those registered with the WINS server.
  193.    * (nmbd_namelistdb.c)
  194.    */
  195.   expire_names(t);
  196.  
  197.   /*
  198.    * Go through all the broadcast subnets and for each
  199.    * workgroup known on that subnet remove any expired
  200.    * server names. If a workgroup has an empty serverlist
  201.    * and has itself timed out then remove the workgroup.
  202.    * (nmbd_workgroupdb.c)
  203.    */
  204.   expire_workgroups_and_servers(t);
  205. } /* expire_names_and_servers */
  206.  
  207. /**************************************************************************** **
  208.   reload the services file
  209.  **************************************************************************** */
  210. BOOL reload_services(BOOL test)
  211. {
  212.   BOOL ret;
  213.   extern fstring remote_machine;
  214.  
  215.   fstrcpy( remote_machine, "nmb" );
  216.  
  217.   if ( lp_loaded() )
  218.   {
  219.     pstring fname;
  220.     pstrcpy( fname,lp_configfile());
  221.     if (file_exist(fname,NULL) && !strcsequal(fname,servicesf))
  222.     {
  223.       pstrcpy(servicesf,fname);
  224.       test = False;
  225.     }
  226.   }
  227.  
  228.   if ( test && !lp_file_list_changed() )
  229.     return(True);
  230.  
  231.   ret = lp_load( servicesf, True );
  232.  
  233.   /* perhaps the config filename is now set */
  234.   if ( !test )
  235.   {
  236.     DEBUG( 3, ( "services not loaded\n" ) );
  237.     reload_services( True );
  238.   }
  239.  
  240.   /* Do a sanity check for a misconfigured nmbd */
  241.   if( lp_wins_support() && *lp_wins_server() )
  242.   {
  243.     DEBUG(0,("ERROR: both 'wins support = true' and 'wins server = <server>' \
  244. cannot be set in the smb.conf file. nmbd aborting.\n"));
  245.     exit(10);
  246.   }
  247.  
  248.   return(ret);
  249. } /* reload_services */
  250.  
  251. /**************************************************************************** **
  252.  The main select loop.
  253.  **************************************************************************** */
  254. static void process(void)
  255. {
  256.   BOOL run_election;
  257.  
  258.   while( True )
  259.   {
  260.     time_t t = time(NULL);
  261.  
  262.     /*
  263.      * Check all broadcast subnets to see if
  264.      * we need to run an election on any of them.
  265.      * (nmbd_elections.c)
  266.      */
  267.     run_election = check_elections();
  268.  
  269.     /*
  270.      * Read incoming UDP packets.
  271.      * (nmbd_packets.c)
  272.      */
  273.     if(listen_for_packets(run_election))
  274.       return;
  275.  
  276.     /*
  277.      * Process all incoming packets
  278.      * read above. This calls the success and
  279.      * failure functions registered when response
  280.      * packets arrrive, and also deals with request
  281.      * packets from other sources.
  282.      * (nmbd_packets.c)
  283.      */
  284.     run_packet_queue();
  285.  
  286.     /*
  287.      * Run any elections - initiate becoming
  288.      * a local master browser if we have won.
  289.      * (nmbd_elections.c)
  290.      */
  291.     run_elections(t);
  292.  
  293.     /*
  294.      * Send out any broadcast announcements
  295.      * of our server names. This also announces
  296.      * the workgroup name if we are a local
  297.      * master browser.
  298.      * (nmbd_sendannounce.c)
  299.      */
  300.     announce_my_server_names(t);
  301.  
  302.     /*
  303.      * Send out any LanMan broadcast announcements
  304.      * of our server names.
  305.      * (nmbd_sendannounce.c)
  306.      */
  307.     announce_my_lm_server_names(t);
  308.  
  309.     /*
  310.      * If we are a local master browser, periodically
  311.      * announce ourselves to the domain master browser.
  312.      * This also deals with syncronising the domain master
  313.      * browser server lists with ourselves as a local
  314.      * master browser.
  315.      * (nmbd_sendannounce.c)
  316.      */
  317.     announce_myself_to_domain_master_browser(t);
  318.  
  319.     /*
  320.      * Fullfill any remote announce requests.
  321.      * (nmbd_sendannounce.c)
  322.      */
  323.     announce_remote(t);
  324.  
  325.     /*
  326.      * Fullfill any remote browse sync announce requests.
  327.      * (nmbd_sendannounce.c)
  328.      */
  329.     browse_sync_remote(t);
  330.  
  331.     /*
  332.      * Scan the broadcast subnets, and WINS client
  333.      * namelists and refresh any that need refreshing.
  334.      * (nmbd_mynames.c)
  335.      */
  336.     refresh_my_names(t);
  337.  
  338.     /*
  339.      * Scan the subnet namelists and server lists and
  340.      * expire thos that have timed out.
  341.      * (nmbd.c)
  342.      */
  343.     expire_names_and_servers(t);
  344.  
  345.     /*
  346.      * Write out a snapshot of our current browse list into
  347.      * the browse.dat file. This is used by smbd to service
  348.      * incoming NetServerEnum calls - used to synchronise
  349.      * browse lists over subnets.
  350.      * (nmbd_serverlistdb.c)
  351.      */
  352.     write_browse_list(t, False);
  353.  
  354.     /*
  355.      * If we are a domain master browser, we have a list of
  356.      * local master browsers we should synchronise browse
  357.      * lists with (these are added by an incoming local
  358.      * master browser announcement packet). Expire any of
  359.      * these that are no longer current, and pull the server
  360.      * lists from each of these known local master browsers.
  361.      * (nmbd_browsesync.c)
  362.      */
  363.     dmb_expire_and_sync_browser_lists(t);
  364.  
  365.     /*
  366.      * Check that there is a local master browser for our
  367.      * workgroup for all our broadcast subnets. If one
  368.      * is not found, start an election (which we ourselves
  369.      * may or may not participate in, depending on the
  370.      * setting of the 'local master' parameter.
  371.      * (nmbd_elections.c)
  372.      */
  373.     check_master_browser_exists(t);
  374.  
  375.     /*
  376.      * If we are configured as a logon server, attempt to
  377.      * register the special NetBIOS names to become such
  378.      * (WORKGROUP<1c> name) on all broadcast subnets and
  379.      * with the WINS server (if used). If we are configured
  380.      * to become a domain master browser, attempt to register
  381.      * the special NetBIOS name (WORKGROUP<1b> name) to
  382.      * become such.
  383.      * (nmbd_become_dmb.c)
  384.      */
  385.     add_domain_names(t);
  386.  
  387.     /*
  388.      * If we are a WINS server, do any timer dependent
  389.      * processing required.
  390.      * (nmbd_winsserver.c)
  391.      */
  392.     initiate_wins_processing(t);
  393.  
  394.     /*
  395.      * If we are a domain master browser, attempt to contact the
  396.      * WINS server to get a list of all known WORKGROUPS/DOMAINS.
  397.      * This will only work to a Samba WINS server.
  398.      * (nmbd_browsesync.c)
  399.      */
  400.     collect_all_workgroup_names_from_wins_server(t);
  401.  
  402.     /*
  403.      * Go through the response record queue and time out or re-transmit
  404.      * and expired entries.
  405.      * (nmbd_packets.c)
  406.      */
  407.     retransmit_or_expire_response_records(t);
  408.   }
  409. } /* process */
  410.  
  411.  
  412. /**************************************************************************** **
  413.  open the socket communication
  414.  **************************************************************************** */
  415. static BOOL open_sockets(BOOL isdaemon, int port)
  416. {
  417.   /* The sockets opened here will be used to receive broadcast
  418.      packets *only*. Interface specific sockets are opened in
  419.      make_subnet() in namedbsubnet.c. Thus we bind to the
  420.      address "0.0.0.0". The parameter 'socket address' is
  421.      now deprecated.
  422.    */
  423.  
  424.   if ( isdaemon )
  425.     ClientNMB = open_socket_in(SOCK_DGRAM, port,0,0);
  426.   else
  427.     ClientNMB = 0;
  428.   
  429.   ClientDGRAM = open_socket_in(SOCK_DGRAM,DGRAM_PORT,3,0);
  430.  
  431.   if ( ClientNMB == -1 )
  432.     return( False );
  433.  
  434.   signal( SIGPIPE, SIGNAL_CAST sig_pipe );
  435.  
  436.   set_socket_options( ClientNMB,   "SO_BROADCAST" );
  437.   set_socket_options( ClientDGRAM, "SO_BROADCAST" );
  438.  
  439.   DEBUG( 3, ( "open_sockets: Broadcast sockets opened.\n" ) );
  440.   return( True );
  441. } /* open_sockets */
  442.  
  443.  
  444. /**************************************************************************** **
  445.  initialise connect, service and file structs
  446.  **************************************************************************** */
  447. static BOOL init_structs(void)
  448. {
  449.   extern fstring local_machine;
  450.   char *p, *ptr;
  451.   int namecount;
  452.   int n;
  453.   int nodup;
  454.   pstring nbname;
  455.  
  456.   if (! *myname)
  457.   {
  458.     fstrcpy( myname, myhostname );
  459.     p = strchr( myname, '.' );
  460.     if (p)
  461.       *p = 0;
  462.   }
  463.   strupper( myname );
  464.  
  465.   /* Add any NETBIOS name aliases. Ensure that the first entry
  466.      is equal to myname.
  467.    */
  468.   /* Work out the max number of netbios aliases that we have */
  469.   ptr = lp_netbios_aliases();
  470.   for( namecount=0; next_token(&ptr,nbname,NULL); namecount++ )
  471.     ;
  472.   if ( *myname )
  473.     namecount++;
  474.  
  475.   /* Allocate space for the netbios aliases */
  476.   my_netbios_names = (char **)malloc( sizeof(char *) * (namecount+1) );
  477.   if( NULL == my_netbios_names )
  478.   {
  479.      DEBUG( 0, ( "init_structs: malloc fail.\n" ) );
  480.      return( False );
  481.   }
  482.  
  483.   /* Use the myname string first */
  484.   namecount=0;
  485.   if ( *myname )
  486.     my_netbios_names[namecount++] = myname;
  487.   
  488.   ptr = lp_netbios_aliases();
  489.   while ( next_token( &ptr, nbname, NULL ) )
  490.   {
  491.     strupper( nbname );
  492.     /* Look for duplicates */
  493.     nodup=1;
  494.     for( n=0; n<namecount; n++ )
  495.     {
  496.       if( 0 == strcmp( nbname, my_netbios_names[n] ) )
  497.         nodup=0;
  498.     }
  499.     if (nodup)
  500.       my_netbios_names[namecount++] = strdup( nbname );
  501.   }
  502.   
  503.   /* Check the strdups succeeded. */
  504.   for( n = 0; n < namecount; n++ )
  505.     if( NULL == my_netbios_names[n] )
  506.     {
  507.       DEBUG(0,("init_structs: malloc fail when allocating names.\n"));
  508.       return False;
  509.     }
  510.   
  511.   /* Terminate name list */
  512.   my_netbios_names[namecount++] = NULL;
  513.   
  514.   fstrcpy( local_machine, myname );
  515.   trim_string( local_machine, " ", " " );
  516.   p = strchr( local_machine, ' ' );
  517.   if (p)
  518.     *p = 0;
  519.   strlower( local_machine );
  520.  
  521.   DEBUG( 5, ("Netbios name list:-\n") );
  522.   for( n=0; my_netbios_names[n]; n++ )
  523.     DEBUG( 5, ( "my_netbios_names[%d]=\"%s\"\n", n, my_netbios_names[n] ) );
  524.  
  525.   return( True );
  526. } /* init_structs */
  527.  
  528. /**************************************************************************** **
  529.  usage on the program
  530.  **************************************************************************** */
  531. static void usage(char *pname)
  532. {
  533.   DEBUG(0,("Incorrect program usage - is the command line correct?\n"));
  534.  
  535.   printf( "Usage: %s [-n name] [-D] [-p port] [-d debuglevel] ", pname );
  536.   printf( "[-l log basename]\n" );
  537.   printf( "Version %s\n", VERSION );
  538.   printf( "\t-D                    become a daemon\n" );
  539.   printf( "\t-p port               listen on the specified port\n" );
  540.   printf( "\t-d debuglevel         set the debuglevel\n" );
  541.   printf( "\t-l log basename.      Basename for log/debug files\n" );
  542.   printf( "\t-n netbiosname.       " );
  543.   printf( "the netbios name to advertise for this host\n");
  544.   printf( "\t-H hosts file         load a netbios hosts file\n" );
  545.   printf( "\n");
  546. } /* usage */
  547.  
  548.  
  549. /**************************************************************************** **
  550.  main program
  551.  **************************************************************************** */
  552. int main(int argc,char *argv[])
  553. {
  554.   int opt;
  555.   extern FILE *dbf;
  556.   extern char *optarg;
  557.   char pidFile[100] = { 0 };
  558.  
  559.   global_nmb_port = NMB_PORT;
  560.  
  561.   *host_file = 0;
  562.  
  563.   global_in_nmbd = True;
  564.  
  565.   StartupTime = time(NULL);
  566.  
  567.   TimeInit();
  568.  
  569.   pstrcpy( debugf, NMBLOGFILE );
  570.  
  571.   setup_logging( argv[0], False );
  572.  
  573.   charset_initialise();
  574.  
  575. #ifdef LMHOSTSFILE
  576.   pstrcpy( host_file, LMHOSTSFILE );
  577. #endif
  578.  
  579.   /* this is for people who can't start the program correctly */
  580.   while (argc > 1 && (*argv[1] != '-'))
  581.   {
  582.     argv++;
  583.     argc--;
  584.   }
  585.  
  586.   fault_setup((void (*)(void *)) fault_continue );
  587.  
  588.   signal( SIGHUP,  SIGNAL_CAST sig_hup );
  589.   signal( SIGTERM, SIGNAL_CAST sig_term );
  590.  
  591.   /* Setup the signals that allow the debug log level
  592.      to by dynamically changed. */
  593.  
  594.   /* If we are using the malloc debug code we can't use
  595.      SIGUSR1 and SIGUSR2 to do debug level changes. */
  596. #ifndef MEM_MAN
  597. #if defined(SIGUSR1)
  598.   signal( SIGUSR1, SIGNAL_CAST sig_usr1 );
  599. #endif /* SIGUSR1 */
  600.  
  601. #if defined(SIGUSR2)
  602.   signal( SIGUSR2, SIGNAL_CAST sig_usr2 );
  603. #endif /* SIGUSR2 */
  604. #endif /* MEM_MAN */
  605.  
  606.   while((opt = getopt(argc, argv, "as:T:I:C:bAi:B:N:Rn:l:d:Dp:hSH:G:f:")) != EOF)
  607.     {
  608.       switch (opt)
  609.         {
  610.         case 'f':
  611.           strncpy(pidFile, optarg, sizeof(pidFile));
  612.           break;
  613.         case 's':
  614.           pstrcpy(servicesf,optarg);
  615.           break;          
  616.         case 'N':
  617.         case 'B':
  618.         case 'I':
  619.         case 'C':
  620.         case 'G':
  621.           DEBUG(0,("Obsolete option '%c' used\n",opt));
  622.           break;
  623.         case 'H':
  624.           pstrcpy(host_file,optarg);
  625.           break;
  626.         case 'n':
  627.           pstrcpy(myname,optarg);
  628.           strupper(myname);
  629.           break;
  630.         case 'l':
  631.           slprintf(debugf,sizeof(debugf)-1, "%s.nmb",optarg);
  632.           break;
  633.         case 'i':
  634.           pstrcpy(scope,optarg);
  635.           strupper(scope);
  636.           break;
  637.         case 'a':
  638.           {
  639.           extern BOOL append_log;
  640.           append_log = !append_log;
  641.           }
  642.           break;
  643.         case 'D':
  644.           is_daemon = True;
  645.           break;
  646.         case 'd':
  647.           DEBUGLEVEL = atoi(optarg);
  648.           break;
  649.         case 'p':
  650.           global_nmb_port = atoi(optarg);
  651.           break;
  652.         case 'h':
  653.           usage(argv[0]);
  654.           exit(0);
  655.           break;
  656.         default:
  657.           if (!is_a_socket(0))
  658.           {
  659.             usage(argv[0]);
  660.           }
  661.           break;
  662.         }
  663.     }
  664.  
  665.   reopen_logs();
  666.  
  667.   DEBUG(1,("%s netbios nameserver version %s started\n",timestring(),VERSION));
  668.   DEBUG(1,("Copyright Andrew Tridgell 1994-1997\n"));
  669.  
  670.   if( !get_myname( myhostname, NULL) )
  671.   {
  672.     DEBUG(0,("Unable to get my hostname - exiting.\n"));
  673.     return -1;
  674.   }
  675.  
  676.   if ( !reload_services(False) )
  677.     return(-1);
  678.  
  679.   codepage_initialise(lp_client_code_page());
  680.  
  681.   if(!init_structs())
  682.     return -1;
  683.  
  684.   reload_services( True );
  685.  
  686.   fstrcpy( myworkgroup, lp_workgroup() );
  687.  
  688.   if (strequal(myworkgroup,"*"))
  689.   {
  690.     DEBUG(0,("ERROR: a workgroup name of * is no longer supported\n"));
  691.     exit(1);
  692.   }
  693.  
  694.   set_samba_nb_type();
  695.  
  696.   if (!is_daemon && !is_a_socket(0))
  697.   {
  698.     DEBUG(0,("standard input is not a socket, assuming -D option\n"));
  699.     is_daemon = True;
  700.   }
  701.   
  702.   if (is_daemon)
  703.   {
  704.     DEBUG(2,("%s becoming a daemon\n",timestring()));
  705.     become_daemon();
  706.   }
  707.  
  708.   if (!directory_exist(lp_lockdir(), NULL))
  709.   {
  710.     mkdir(lp_lockdir(), 0755);
  711.   }
  712.  
  713.   if (*pidFile)
  714.   {
  715.     int     fd;
  716.     char    buf[20];
  717.  
  718. #ifdef O_NONBLOCK
  719.     fd = open( pidFile, O_NONBLOCK | O_CREAT | O_WRONLY | O_TRUNC, 0644 );
  720. #else
  721.     fd = open( pidFile, O_CREAT | O_WRONLY | O_TRUNC, 0644 );
  722. #endif
  723.     if ( fd < 0 )
  724.     {
  725.       DEBUG(0,("ERROR: can't open %s: %s\n", pidFile, strerror(errno)));
  726.       exit(1);
  727.     }
  728.     if (fcntl_lock(fd,F_SETLK,0,1,F_WRLCK)==False)
  729.     {
  730.       DEBUG(0,("ERROR: nmbd is already running\n"));
  731.       exit(1);
  732.     }
  733.     slprintf(buf, sizeof(buf)-1, "%u\n", (unsigned int) getpid());
  734.     if (write(fd, buf, strlen(buf)) < 0)
  735.     {
  736.       DEBUG(0,("ERROR: can't write to %s: %s\n", pidFile, strerror(errno)));
  737.       exit(1);
  738.     }
  739.       /* Leave pid file open & locked for the duration... */
  740.   }
  741.  
  742.  
  743.   DEBUG( 3, ( "Opening sockets %d\n", global_nmb_port ) );
  744.  
  745.   if ( !open_sockets( is_daemon, global_nmb_port ) )
  746.     return 1;
  747.  
  748.   /* Determine all the IP addresses we have. */
  749.   load_interfaces();
  750.  
  751.   /* Create an nmbd subnet record for each of the above. */
  752.   if( False == create_subnets() )
  753.   {
  754.     DEBUG(0,("ERROR: Failed when creating subnet lists. Exiting.\n"));
  755.     exit(1);
  756.   }
  757.  
  758.   /* Load in any static local names. */ 
  759.   if ( *host_file )
  760.   {
  761.     load_lmhosts_file(host_file);
  762.     DEBUG(3,("Loaded hosts file\n"));
  763.   }
  764.  
  765.   /* If we are acting as a WINS server, initialise data structures. */
  766.   if( !initialise_wins() )
  767.   {
  768.     DEBUG( 0, ( "nmbd: Failed when initialising WINS server.\n" ) );
  769.     exit(1);
  770.   }
  771.  
  772.   /* 
  773.    * Register nmbd primary workgroup and nmbd names on all
  774.    * the broadcast subnets, and on the WINS server (if specified).
  775.    * Also initiate the startup of our primary workgroup (start
  776.    * elections if we are setup as being able to be a local
  777.    * master browser.
  778.    */
  779.  
  780.   if( False == register_my_workgroup_and_names() )
  781.   {
  782.     DEBUG(0,("ERROR: Failed when creating my my workgroup. Exiting.\n"));
  783.     exit(1);
  784.   }
  785.  
  786.   /* We can only take signals in the select. */
  787.   BlockSignals( True, SIGTERM );
  788. #if defined(SIGUSR1)
  789.   BlockSignals( True, SIGUSR1);
  790. #endif /* SIGUSR1 */
  791. #if defined(SIGUSR2)
  792.   BlockSignals( True, SIGUSR2);
  793. #endif /* SIGUSR2 */
  794.  
  795.   process();
  796.   close_sockets();
  797.  
  798.   if (dbf)
  799.     fclose(dbf);
  800.   return(0);
  801. } /* main */
  802.  
  803. /* ========================================================================== */
  804.